﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.SweptVolume.CApSVInterferenceZone
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using Microsoft.CSharp.RuntimeBinder;
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands.SweptVolume;

public class CApSVInterferenceZone
{
  private const double minimalIZTimeInterval = 0.05;
  private ITxSweptVolumeHoldingObject m_simulatingObject;
  private ITxLocatableObject m_checkWithObject;
  private double m_clearance;
  private bool m_tcpTrack;
  private bool m_refreshDisplay;
  private bool m_createNotes;
  private bool m_includeCables;
  protected CApSVInterferenceZoneSamplingManager m_samplingManager;
  private TxObjectList m_createdTCPFTrackComponents;
  private const int IZ_ZONE_DATA_FIRST_ROW = 8;

  internal event CApSimulationHandler_SimulationInitializedEventHandler SimulationInitialized;

  public CApSVInterferenceZone()
  {
    this.m_simulatingObject = (ITxSweptVolumeHoldingObject) null;
    this.m_checkWithObject = (ITxLocatableObject) null;
    this.m_clearance = 0.0;
    this.m_tcpTrack = false;
    this.m_refreshDisplay = false;
    this.m_createNotes = false;
    this.m_createdTCPFTrackComponents = new TxObjectList();
    this.m_samplingManager = (CApSVInterferenceZoneSamplingManager) null;
  }

  public bool TCPTrack
  {
    get => this.m_tcpTrack;
    set => this.m_tcpTrack = value;
  }

  public bool RefreshDisplay
  {
    get => this.m_refreshDisplay;
    set => this.m_refreshDisplay = value;
  }

  public bool CreateNotes
  {
    get => this.m_createNotes;
    set => this.m_createNotes = value;
  }

  public double Clearance
  {
    get => this.m_clearance;
    set => this.m_clearance = value;
  }

  public EApInterferenceZoneErrorType Error => this.m_samplingManager.Error;

  public void sampleInterferenceZone(
    ITxSweptVolumeHoldingObject simulatingObject,
    ITxLocatableObject checkWithObj,
    bool includeCables)
  {
    this.m_simulatingObject = simulatingObject;
    this.m_checkWithObject = checkWithObj;
    this.m_includeCables = includeCables;
    this.initSamplingManager();
    this.m_samplingManager.startSampling();
    this.onSamplingEnded();
  }

  public void generateReport()
  {
    if (this.m_samplingManager == null || this.m_samplingManager.InterferenceZones == null)
      return;
    this.generateExcelReport(this.m_samplingManager.InterferenceZones);
  }

  public void deleteTCPFTrackerComponents()
  {
    foreach (ITxObject tcpfTrackComponent in (Collection<ITxObject>) this.m_createdTCPFTrackComponents)
      tcpfTrackComponent.Delete();
  }

  protected virtual void initSamplingManager()
  {
    double timeInterval = TxApplication.Options.Motion.TimeInterval;
    if (0.05 < timeInterval)
      timeInterval = 0.05;
    CApSVTimeSampleSimulationHandler simHandler;
    if (this.m_simulatingObject is ITxOrderedCompoundOperation)
      simHandler = new CApSVTimeSampleSimulationHandler(this.m_simulatingObject as ITxOrderedCompoundOperation, timeInterval);
    else
      simHandler = this.m_simulatingObject is ITxRoboticProgram ? new CApSVTimeSampleSimulationHandler(this.m_simulatingObject as ITxRoboticProgram, timeInterval) : throw new InvalidOperationException("Unsupported simulation object: " + this.m_simulatingObject.ToString());
    simHandler.RefreshDisplay = this.RefreshDisplay;
    this.m_samplingManager = new CApSVInterferenceZoneSamplingManager(simHandler, new CApSVSamplingObjectsHandler((ITxObject) (CApSVUtilities.getRootObject(this.m_simulatingObject) ?? throw new Exception("CApSVInterferenceZone: sampleInterferenceZone: operation does not have a root object")), this.m_includeCables)
    {
      TreatDeviceAsLinks = false
    }, this.m_checkWithObject, this.m_includeCables);
    this.m_samplingManager.TCPTrack = this.m_tcpTrack;
    this.m_samplingManager.Clearance = this.m_clearance;
    this.m_samplingManager.SimulationHandler.SimulationInitialized += new CApSimulationHandler_SimulationInitializedEventHandler(this.m_samplingManager_SimulationInitialized);
  }

  protected virtual void onSamplingEnded()
  {
    if (this.m_samplingManager.CreatedTCPFTrackComponents != null && ((Collection<ITxObject>) this.m_samplingManager.CreatedTCPFTrackComponents).Count > 0)
    {
      foreach (ITxObject tcpfTrackComponent in (Collection<ITxObject>) this.m_samplingManager.CreatedTCPFTrackComponents)
      {
        if (!((Collection<ITxObject>) this.m_createdTCPFTrackComponents).Contains(tcpfTrackComponent))
          ((Collection<ITxObject>) this.m_createdTCPFTrackComponents).Add(tcpfTrackComponent);
      }
    }
    if (this.m_samplingManager.Error != EApInterferenceZoneErrorType.NO_ERROR || !this.m_createNotes)
      return;
    this.createNotes();
  }

  private string getFromRM(string key)
  {
    string fromRm = "N/A";
    string str = new ResourceManager("DnProcessSimulateCommands.SweptVolume.StringTable", this.GetType().Assembly).GetString(key);
    if (str != null)
      fromRm = str;
    return fromRm;
  }

  private void createNotes()
  {
    if (this.m_samplingManager == null || this.m_samplingManager.InterferenceZones == null || this.m_samplingManager.InterferenceZones.Length == 0)
      return;
    for (int index = 0; index < this.m_samplingManager.InterferenceZones.Length; ++index)
    {
      CApSVInterferenceZoneData interferenceZone = this.m_samplingManager.InterferenceZones[index];
      this.createNotesForInterferenceZone(index + 1, interferenceZone);
    }
  }

  private void createNotesForInterferenceZone(int index, CApSVInterferenceZoneData zoneData)
  {
    TxPhysicalRoot physicalRoot = TxApplication.ActiveDocument.PhysicalRoot;
    string[] strArray = new string[2]{ "Enter", "Exit" };
    CApSVInterferenceZoneGateData[] interferenceZoneGateDataArray = new CApSVInterferenceZoneGateData[2]
    {
      zoneData.Enter,
      zoneData.Exit
    };
    for (int index1 = 0; index1 < interferenceZoneGateDataArray.Length; ++index1)
    {
      string str1 = strArray[index1];
      ITxLocatableObject locationOutside = interferenceZoneGateDataArray[index1].LocationOutside as ITxLocatableObject;
      string str2 = $"Interference_Zone_{zoneData.Operation.Name}_{((ITxObject) zoneData.CheckWithObject).Name}_{index.ToString()}_{str1}";
      TxNoteCreationData noteCreationData = new TxNoteCreationData(physicalRoot.GetUniqueDisplayName(str2), locationOutside);
      TxNote note = physicalRoot.CreateNote(noteCreationData);
      note.Text = $"{str1} Zone {index.ToString()}\n\r";
      TxNote txNote1 = note;
      txNote1.Text = $"{txNote1.Text}{this.getObjectName((ITxObject) locationOutside)}\n\r";
      TxNote txNote2 = note;
      txNote2.Text = $"{txNote2.Text}{this.getObjectName((ITxObject) zoneData.SimulatedObject)}\n\r";
      TxNote txNote3 = note;
      txNote3.Text = $"{txNote3.Text}{this.getObjectName(zoneData.Operation)}\n\r";
      TxNote txNote4 = note;
      txNote4.Text = $"{txNote4.Text}{this.getObjectName((ITxObject) zoneData.CheckWithObject)}\n\r";
    }
  }

  private void m_samplingManager_SimulationInitialized(object sender, EventArgs e)
  {
    if (this.SimulationInitialized == null)
      return;
    this.SimulationInitialized(sender, e);
  }

  private void generateExcelReport(CApSVInterferenceZoneData[] zonesData)
  {
    CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
    try
    {
      // ISSUE: variable of a compiler-generated type
      Microsoft.Office.Interop.Excel.Application instance = (Microsoft.Office.Interop.Excel.Application) Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("00024500-0000-0000-C000-000000000046")));
      instance.Visible = true;
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
      // ISSUE: reference to a compiler-generated method
      // ISSUE: variable of a compiler-generated type
      _Workbook workbook = (_Workbook) instance.Workbooks.Add((object) Missing.Value);
      // ISSUE: reference to a compiler-generated field
      if (CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__0 == null)
      {
        // ISSUE: reference to a compiler-generated field
        CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__0 = CallSite<Func<CallSite, object, _Worksheet>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof (_Worksheet), typeof (CApSVInterferenceZone)));
      }
      // ISSUE: reference to a compiler-generated field
      // ISSUE: reference to a compiler-generated field
      // ISSUE: variable of a compiler-generated type
      _Worksheet oSheet = CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__0.Target((CallSite) CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__0, workbook.ActiveSheet);
      this.initRowHeaders(oSheet);
      for (int index = 0; index < zonesData.Length; ++index)
      {
        oSheet.Cells[(object) 1, (object) (index + 2)] = (object) ("Zone " + (index + 1).ToString());
        // ISSUE: reference to a compiler-generated field
        if (CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__1 == null)
        {
          // ISSUE: reference to a compiler-generated field
          CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__1 = CallSite<Func<CallSite, object, Range>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof (Range), typeof (CApSVInterferenceZone)));
        }
        // ISSUE: reference to a compiler-generated field
        // ISSUE: reference to a compiler-generated field
        // ISSUE: variable of a compiler-generated type
        Range oRng1 = CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__1.Target((CallSite) CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__1, oSheet.Cells[(object) 1, (object) (index + 2)]);
        this.initColumnHeaders(oRng1, zonesData[index]);
        // ISSUE: reference to a compiler-generated field
        if (CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__2 == null)
        {
          // ISSUE: reference to a compiler-generated field
          CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__2 = CallSite<Func<CallSite, object, Range>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.Convert(CSharpBinderFlags.ConvertExplicit, typeof (Range), typeof (CApSVInterferenceZone)));
        }
        // ISSUE: reference to a compiler-generated field
        // ISSUE: reference to a compiler-generated field
        // ISSUE: variable of a compiler-generated type
        Range oRng2 = CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__2.Target((CallSite) CApSVInterferenceZone.\u003C\u003Eo__38.\u003C\u003Ep__2, oSheet.Cells[(object) 8, (object) (index + 2)]);
        this.createColumnForIZ(oRng2, zonesData[index]);
      }
      // ISSUE: reference to a compiler-generated method
      // ISSUE: variable of a compiler-generated type
      Range range = oSheet.get_Range((object) "A1", (object) "A1");
      range.EntireColumn.VerticalAlignment = (object) XlVAlign.xlVAlignCenter;
      range.EntireRow.VerticalAlignment = (object) XlVAlign.xlVAlignCenter;
      // ISSUE: reference to a compiler-generated method
      range.EntireColumn.AutoFit();
      instance.Visible = true;
      instance.UserControl = true;
    }
    catch (Exception ex)
    {
      int num = (int) TxMessageBox.Show("Error: " + ex.Message + " Line: " + ex.Source, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
    }
    finally
    {
      Thread.CurrentThread.CurrentCulture = currentCulture;
    }
  }

  private void initRowHeaders(_Worksheet oSheet)
  {
    string str1 = $" [{TxApplication.Options.Units.TimeUnitName}]";
    string str2 = $" [{TxApplication.Options.Units.LinearUnitName}]";
    int RowIndex = 1;
    oSheet.Cells[(object) RowIndex, (object) 1] = (object) this.getFromRM("IZ_REPORT_ZONE_NAME");
    int num1;
    oSheet.Cells[(object) (num1 = RowIndex + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_OPERATION_NAME");
    int num2;
    oSheet.Cells[(object) (num2 = num1 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_SIMULATED_OBJECT");
    int num3;
    oSheet.Cells[(object) (num3 = num2 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_INTERFERES_WITH");
    int num4;
    oSheet.Cells[(object) (num4 = num3 + 1), (object) 1] = (object) (this.getFromRM("IZ_REPORT_TIME_IN_ZONE") + str1);
    int num5 = num4 + 1;
    int num6;
    oSheet.Cells[(object) (num6 = num5 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_ZONE_ENTRANCE");
    int num7;
    oSheet.Cells[(object) (num7 = num6 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_LOCATION_OUTSIDE");
    int num8;
    oSheet.Cells[(object) (num8 = num7 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_LOCATION_INSIDE");
    int num9;
    oSheet.Cells[(object) (num9 = num8 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_NEAREST_OBJECT_TO_ZONE");
    int num10;
    oSheet.Cells[(object) (num10 = num9 + 1), (object) 1] = (object) (this.getFromRM("IZ_REPORT_DISTANCE_TO_ZONE") + str2);
    int num11;
    oSheet.Cells[(object) (num11 = num10 + 1), (object) 1] = (object) (this.getFromRM("IZ_REPORT_TIME_TO_ZONE") + str1);
    int num12;
    oSheet.Cells[(object) (num12 = num11 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_UNREACHED_LOCATIONS");
    int num13 = num12 + 1;
    int num14;
    oSheet.Cells[(object) (num14 = num13 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_ZONE_EXIT");
    int num15;
    oSheet.Cells[(object) (num15 = num14 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_LOCATION_INSIDE");
    int num16;
    oSheet.Cells[(object) (num16 = num15 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_LOCATION_OUTSIDE");
    int num17;
    oSheet.Cells[(object) (num17 = num16 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_NEAREST_OBJECT_TO_ZONE");
    int num18;
    oSheet.Cells[(object) (num18 = num17 + 1), (object) 1] = (object) (this.getFromRM("IZ_REPORT_DISTANCE_FROM_ZONE") + str2);
    int num19;
    oSheet.Cells[(object) (num19 = num18 + 1), (object) 1] = (object) (this.getFromRM("IZ_REPORT_TIME_FROM_ZONE") + str1);
    int num20;
    oSheet.Cells[(object) (num20 = num19 + 1), (object) 1] = (object) this.getFromRM("IZ_REPORT_UNREACHED_LOCATIONS");
    // ISSUE: reference to a compiler-generated method
    oSheet.get_Range((object) "A1", (object) "A1").EntireColumn.Font.Bold = (object) true;
    // ISSUE: reference to a compiler-generated method
    oSheet.get_Range((object) "A1", (object) "A1").EntireRow.Font.Bold = (object) true;
    // ISSUE: reference to a compiler-generated method
    oSheet.get_Range((object) "A2", (object) "A5").Font.Bold = (object) false;
    // ISSUE: reference to a compiler-generated method
    oSheet.get_Range((object) "A8", (object) "A13").Font.Bold = (object) false;
    // ISSUE: reference to a compiler-generated method
    oSheet.get_Range((object) "A16", (object) "A21").Font.Bold = (object) false;
  }

  private void initColumnHeaders(Range oRng, CApSVInterferenceZoneData zoneData)
  {
    int RowOffset = 1;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) RowOffset, (object) 0).Value2 = (object) this.getObjectName(zoneData.Operation);
    int num1;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num1 = RowOffset + 1), (object) 0).Value2 = (object) this.getObjectName((ITxObject) zoneData.SimulatedObject);
    int num2;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num2 = num1 + 1), (object) 0).Value2 = (object) this.getObjectName((ITxObject) zoneData.CheckWithObject);
    int num3;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num3 = num2 + 1), (object) 0).Value2 = (object) this.formatTime(this.getTimeInZone(zoneData));
  }

  private void createColumnForIZ(Range oRng, CApSVInterferenceZoneData zoneData)
  {
    int RowOffset = 0;
    CApSVInterferenceZoneGateData enter = zoneData.Enter;
    CApSVInterferenceZoneGateData exit = zoneData.Exit;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) RowOffset, (object) 0).Value2 = (object) this.getObjectName((ITxObject) enter.LocationOutside);
    int num1;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num1 = RowOffset + 1), (object) 0).Value2 = (object) this.getObjectName((ITxObject) enter.LocationInside);
    int num2;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num2 = num1 + 1), (object) 0).Value2 = (object) this.getObjectName((ITxObject) enter.NearestObject);
    int num3;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num3 = num2 + 1), (object) 0).Value2 = (object) this.formatLinear(enter.Distance);
    int num4;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num4 = num3 + 1), (object) 0).Value2 = (object) this.formatTime(this.getTimeDifferenceBetweenOutsideAndZone(enter));
    int num5;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num5 = num4 + 1), (object) 0).Value2 = (object) this.getUnreachedLocations(enter.UnReachedLocations);
    int num6 = num5 + 1 + 1;
    int num7;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num7 = num6 + 1), (object) 0).Value2 = (object) this.getObjectName((ITxObject) exit.LocationInside);
    int num8;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num8 = num7 + 1), (object) 0).Value2 = (object) this.getObjectName((ITxObject) exit.LocationOutside);
    int num9;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num9 = num8 + 1), (object) 0).Value2 = (object) this.getObjectName((ITxObject) exit.NearestObject);
    int num10;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num10 = num9 + 1), (object) 0).Value2 = (object) this.formatLinear(exit.Distance);
    int num11;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num11 = num10 + 1), (object) 0).Value2 = (object) this.formatTime(this.getTimeDifferenceBetweenOutsideAndZone(exit));
    int num12;
    // ISSUE: reference to a compiler-generated method
    oRng.get_Offset((object) (num12 = num11 + 1), (object) 0).Value2 = (object) this.getUnreachedLocations(exit.UnReachedLocations);
    // ISSUE: reference to a compiler-generated method
    oRng.EntireColumn.AutoFit();
    oRng.EntireColumn.VerticalAlignment = (object) XlVAlign.xlVAlignCenter;
    oRng.EntireColumn.HorizontalAlignment = (object) XlHAlign.xlHAlignLeft;
  }

  private string getObjectName(ITxObject obj)
  {
    string objectName = "N/A";
    if (obj != null)
      objectName = obj.Name;
    return objectName;
  }

  private double timeDifference(double t1, double t2) => Math.Abs(Math.Round(t2 - t1, 3));

  private double getTimeDifferenceBetweenOutsideAndZone(CApSVInterferenceZoneGateData gateData)
  {
    return this.timeDifference(gateData.TimeAtZone, gateData.TimeAtOutsideLocation);
  }

  private double getTimeInZone(CApSVInterferenceZoneData zoneData)
  {
    return this.timeDifference(zoneData.Enter.TimeAtZone, zoneData.Exit.TimeAtZone);
  }

  private string getUnreachedLocations(ITxLocationOperation[] locOps)
  {
    string unreachedLocations = "N/A";
    if (locOps != null && locOps.Length != 0)
    {
      string[] strArray = new string[locOps.Length];
      for (int index = 0; index < strArray.Length; ++index)
        strArray[index] = ((ITxObject) locOps[index]).Name;
      unreachedLocations = string.Join(", ", strArray);
    }
    return unreachedLocations;
  }

  private string formatTime(double time)
  {
    double timeMultiplier = TxApplication.Options.Units.TimeMultiplier;
    int afterDecimalPoint = TxApplication.Options.Units.TimeDigitsAfterDecimalPoint;
    return Math.Round(time / timeMultiplier, afterDecimalPoint).ToString();
  }

  private string formatLinear(double distance)
  {
    double linearMultiplier = TxApplication.Options.Units.LinearMultiplier;
    int afterDecimalPoint = TxApplication.Options.Units.LinearDigitsAfterDecimalPoint;
    return Math.Round(distance / linearMultiplier, afterDecimalPoint).ToString();
  }
}
